/*
 * 说明
 * 本文件为公共js,请勿随意修改本文件
 * 文件中封装了系统中常用的方法,请根据注释直接传入配置项即可在vue实例中调用
 * 以下方法基本与业务相关,常用的数据处理方法请参照Underscore.js
 * 作者:shelly
 */

// 常用数据操作方法
/***********************************************************************************************
 *@method : ajax
 *@desc   : ajax请求
 *@param  : {String}url:请求的接口
 *@param  : {obj}oData:请求的参数,例如{type:'机型',model:'t43',page:1,rows:10}
 *@param  : {function}callback:用于请求的回调函数,参数data,获取请求成功的数据
 *@param  : {obj}ajax拓展参数，可以覆盖默认参数
 *@return : void
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.ajax = function (url, oData, successCb, errorCb, options) {
    var _this = this;
    oData = oData || {};
    options = options || {};
    var _options = {
        traditional: true,
        async: true,
        type: 'POST',
        dataType: 'json',
        url: url,
        data: oData,
        timeout: 30000, // 默认超时时间为30秒
        success: function (data) {
            successCb && successCb(data);
        },
        error: function (request, error) {
            var msg = '请求出错啦,请稍后重试';
            if (error == 'timeout') { // 处理超时的逻辑
                msg = '请求超时啦';
            }
            errorCb ? errorCb() : _this.$message(msg);
        }
    };
    _.extend(_options, options);
    $.ajax(_options);
};

/***********************************************************************************************
 *@method : ccAjax
 *@desc   : ajax请求
 *@param  : {obj}opt:拓展参数，可以覆盖默认参数
 *@return : void
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.ccAjax = function (opt) {
    var _this = this;
    var d = $.Deferred();
    var _options = {
        traditional: true,
        async: true,
        type: 'POST',
        dataType: 'json',
        timeout: 3000, // 默认超时时间为30秒
        success: function (data) {
            setTimeout(function () {
                ajaxLoading.close();
            }, 0)

            d.resolve(data)
        },
        error: function (request, error) {
            ajaxLoading.close();
            var msg = '请求出错啦,请稍后重试';
            if (opt.errorFlag) { // 外部传入处理
                d.reject(request, error)
            } else { // 内部自行处理
                if (error === 'timeout') { // 处理超时
                    msg = '请求超时啦';
                }
                _this.$message(msg);
            }
        }
    };
    $.extend(_options, opt);
    var ajaxLoading = this.$loading({body: true});
    $.ajax(_options);
    return d;
};

/***********************************************************************************************
 *@method : ccJsonpAjax
 *@desc   : ajax跨域请求
 *@param  : {obj}opt:拓展参数，可以覆盖默认参数
 *@return : void
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.ccJsonpAjax = function (opt) {
    var _this = this;
    var d = $.Deferred();
    var _options = {
        traditional: true,
        type: 'GET',
        async: false,
        dataType: 'jsonp',
        jsonpCallback: 'jsonCb' + Date.now(), // 利用不同返回名 避免变量回收出错
        success: function (data) {
            ajaxLoading.close();
            d.resolve(data)
        },
        error: function (request, error) {
            ajaxLoading.close();
            var msg = '请求出错啦,请稍后重试';
            if (opt.errorFlag) { // 外部传入处理
                d.reject(request, error)
            } else { // 内部自行处理
                if (error === 'timeout') { // 处理超时
                    msg = '请求超时啦';
                }
                _this.$message(msg);
            }
        }
    };
    $.extend(_options, opt);
    var ajaxLoading = this.$loading({body: true});
    $.ajax(_options);
    return d;
};

/***********************************************************************************************
 *@method : getPathByKey
 *@desc   : 获取节点在树中的路径
 *@param  : {String}key:要查找的键值
 *@param  : {}value:对应的数值
 *@param  : {Array}tree:带遍历的树
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.getPathByKey = function (key, value, tree) {

    //定义变量保存当前结果路径
    var temppath = [];
    try {
        function getNodePath(nodes) {
            for (var n = 0; n < nodes.length; n++) {
                var node = nodes[n];
                var nodeValue = node[key];
                temppath.push(nodeValue);

                // 如果找到符合条件的节点则返回
                if (nodeValue === value) {
                    throw "got it~";
                }

                var nodeChildren = nodes[n].children;
                if (nodeChildren && nodeChildren.length) {
                    getNodePath(nodeChildren);
                    //当前节点的子节点遍历完依旧没找到，则删除路径中的该节点
                    temppath.pop();
                } else {
                    //找到叶子节点时，删除路径当中的该叶子节点
                    temppath.pop();
                }
            }
        }

        getNodePath(tree);
    }
    catch (e) {
        return temppath;
    }
};

/***********************************************************************************************
 *@method : deepClone
 *@desc   : 深拷贝
 *@param  : obj:待克隆的对象
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.deepClone = function (obj) {
    var _this = this;
    var o;
    switch (typeof obj) {
        case 'undefined':
            break;
        case 'string':
            o = obj + '';
            break;
        case 'number':
            o = obj - 0;
            break;
        case 'boolean':
            o = obj;
            break;
        case 'object':
            if (obj === null) {
                o = null;
            } else {
                if (obj instanceof Array) {
                    o = [];
                    for (var i = 0, len = obj.length; i < len; i++) {
                        o.push(_this.deepClone(obj[i]));
                    }
                } else {
                    o = {};
                    for (var k in obj) {
                        o[k] = _this.deepClone(obj[k]);
                    }
                }
            }
            break;
        default:
            o = obj;
            break;
    }
    return o;
};

/***********************************************************************************************
 *@method : uniqueArrByKeys
 *@desc   : 数组元素是对象时的去重方法
 *@param  : {Array}arr:待去重的数组
 *@param  : {Array}keys:参照的键值
 *@return : {Array}newArr:去重后的数组
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.uniqueArrByKeys = function (arr, keys) {
    var newArr = [];
    var hash = {};
    for (var i = 0, j = arr.length; i < j; i++) {
        var obj = arr[i];
        // 将对象转成字符串
        var n = keys.length, key = [];
        while (n--) {
            key.push(obj[keys[n]]);
        }
        var k = key.join('|');
        // 使用转换后的字符串进行比较
        if (!(k in hash)) {
            hash[k] = true;
            newArr.push(arr[i]);
        }
    }
    return newArr;
};

/***********************************************************************************************
 *@method : findIndexByKeys
 *@desc   : 数组元素是对象时的确认下标方法
 *@param  : {Object}target:要查找的对象
 *@param  : {Array}arr:待查找数组
 *@param  : {Array}keys:参照的键值
 *@return : {Number}index:对象在数组中的位置
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.findIndexByKeys = function (target, arr, keys) {
    var index = -1;
    var tKey = [];
    for (var n = 0; n < keys.length; n++) {
        tKey.push(target[keys[n]]);
    }
    var tKeyStr = tKey.join('|');

    for (var i = 0, j = arr.length; i < j; i++) {
        var obj = arr[i];
        // 将对象转成字符串
        var key = [];
        for (var n = 0; n < keys.length; n++) {
            key.push(obj[keys[n]]);
        }
        if (key.join('|') === tKeyStr) {
            index = i;
            break;
        }
    }
    return index;
};

// 常用数据转换方法
/***********************************************************************************************
 *@method : convertDict2Select
 *@desc   : 将需要通过接口获取的数据字典转换成下拉选择框的选项
 *@param  : {String}url:请求的接口
 *@param  : {String}label:选择项的内容
 *@param  : {String}value:选择项的value
 *@return : {Array}options:选项数组
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.convertDict2Select = function (data, label, value) {
    var options = [];
    data.forEach(function (datum, i) {
        options.push({
            label: datum[label],
            value: datum[value]
        })
    });
    return options;
};

/***********************************************************************************************
 *@method : convertSource2Cn
 *@desc   : 将内容源转为对应的中文 o_iqiyi爱奇艺,o_tencent腾讯,o_voole优朋
 *@param  : {String}source:内容源的英文表示
 *@return : {String}sourceCn:内容源的中文表示
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.convertSource2Cn = function (source) {
    var sourceCn = {
        'o_iqiyi': '爱奇艺',
        'o_tencent': '腾讯',
        'o_voole': '优朋',
        'yinhe': '爱奇艺',
        'tencent': '腾讯'
    };
    return sourceCn[source];
};

/***********************************************************************************************
 *@method : convertNum2AuditStatus
 *@desc   : 将数字转为对应的审核状态 0下架,1上架,2草稿,3待审核,4审核通过,5审核不通过
 *@param  : {Number}num:审核状态对应的数字
 *@return : {String}auditStatus:审核状态的文字表示
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.convertNum2AuditStatus = function (num) {
    var auditStatus = ['下架', '上架', '待审核', '审核不通过', '审核中', '审核通过', '草稿'];
    return auditStatus[num];
};

/***********************************************************************************************
 *@method : convertNum2BusinessType
 *@desc   : 将数字转为对应的业务分类 0影视
 *@param  : {Number}num:审核状态对应的数字
 *@return : {String}auditStatus:审核状态的文字表示
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.convertNum2BusinessType = function (num) {
    var auditStatus = ['影视'];
    return auditStatus[num];
};

// 常用页面操作方法
/***********************************************************************************************
 *@method : getUrlQueryString
 *@desc   : 获取页面url中的参数值
 *@param  : {String}name:参数名
 *@return : {String}value:参数值
 *@author shelly
 ***********************************************************************************************/
Vue.prototype.getUrlQueryString = function (name) {
    var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
    var r = window.location.search.substr(1).match(reg);
    if (r != null) {
        return decodeURIComponent(r[2]);
    }
    return null;
};
/***********************************************************************************************
 *@method : getSearchParams
 *@desc   : 获取分页查询的参数
 *@param  : {obj}tableForm:参数名
 *@return : {obj}searchForm:分页查询参数
 *@author bjh
 * @date 2019-01-18
 ***********************************************************************************************/
Vue.prototype.getSearchParams = function (searchForm) {
    var searchParams;
    searchParams = {};
    for (var key in searchForm) {
        var param = searchForm[key];
        searchParams[key] = param;
        searchParams[key].value = param.default || ''; // 对于有默认值的列 预置默认值
    }
    return searchParams;
};

/***********************************************************************************************
 *@method : getFinalKeyValList
 *@desc   : 获取最终的key-value列表
 *@param  : {Array}keyValList:参数名
 *@return : {Array}
 *@author bjh
 * @date 2019-04-18
 ***********************************************************************************************/
Vue.prototype.getFinalKeyValList = function (keyValList) {
    var temp = {key: '', value: ''};
    var finalList = [];
    if (JSON.stringify(keyValList) === '[]') {
        finalList.push(temp);
    } else {
        var last = keyValList.pop();

        if (last && (last.key || last.value)) {
            finalList = finalList.concat(keyValList, [last]);
            finalList.push(temp);
        }
    }
    return finalList;
};

/***********************************************************************************************
 *@method : getTrimKeyValList
 *@desc   : 获取去除空值的key-value列表
 *@param  : {Array}keyValList:参数名
 *@return : {Array}
 *@author bjh
 * @date 2019-04-18
 ***********************************************************************************************/
Vue.prototype.getTrimKeyValList = function (keyValList) {
    var finalList = [];
    var length = keyValList.length;
    var index = 0;
    for(; index < length; index++){
        var item = keyValList[index];
        if (item && item.key && item.value){
            var finalItem = {};
            finalItem.key = item.key.trim();
            finalItem.value = item.value.trim();
           finalList.push(finalItem);
        }
    }
    return finalList;
};
/**
 * key:val键值对转化对象
 * @param keyValueStr
 * @returns {object}
 */
Vue.prototype.convert2KeyValObj = function (keyValueStr) {
    var result;
    result = {};
    var list = keyValueStr.split("\n");
    var index = 0;
    var size = list.length;
    for (; index < size; index++) {
        var pair = list[index];
        if (pair === '') {
            continue;
        }
        var keyVal = new Array();
        keyVal = pair.split(":");
        if (keyVal[0] !== '' || keyVal[1] !== '') {
            result[keyVal[0].trim()] = keyVal[1].trim();
        }
    }
    return result;
};
/**
 * obj转化key：val
 * @param jsonData
 * @returns {string}
 */
Vue.prototype.convertObj2KeyVal = function (jsonData) {
    var obj = JSON.parse(JSON.stringify(jsonData))
    var result = [];
    for (var key in  obj) {
        result.push(key.trim() + ":" + obj[key])
    }
    return result.join("\n");
};
/**
 * <code>
 *      keyValueList: [
 {
     key: '',
     value: ''
 }
 ]
 * </code>
 * 转化key:val字符串
 * @param keyValueList
 * @returns {string}
 */
Vue.prototype.convertList2KeyValStr = function (keyValueList) {
    var index = 0;
    var size = keyValueList.length;
    var temp = [];
    for (; index < size; index++) {
        var keyVal = keyValueList[index];
        var tempStr = keyVal.key + ":" + keyVal.value;
        if (tempStr === ':') {
            continue;
        }
        temp.push(tempStr);
    }
    return temp.join("\n")
};
/**
 * key:val字符串转化键值对列表
 * @param keyValueStr
 * @returns {Array}
 */
Vue.prototype.convertkeyValStr2List = function (keyValueStr) {
    var result = [];
    if (keyValueStr === '') {
        var temp = {key: '', value: ''};
        result.push(temp)
        return result;
    }
    var list = keyValueStr.split("\n");
    var index = 0;
    var size = list.length;
    for (; index < size; index++) {
        var pair = list[index];
        if (pair === '') {
            continue;
        }
        var keyVal = new Array();
        keyVal = pair.split(":");
        if (keyVal[0] !== '' || keyVal[1] !== '') {
            var obj = {};
            obj.key = keyVal[0];
            obj.value = keyVal[1];
            result.push(obj);
        }
    }
    result = this.getFinalKeyValList(result);
    return result;
};
/**
 * 获取非空值-通过key
 * @param obj
 * @param key
 * @returns {String}
 */
Vue.prototype.getAvoidNullStringVal = function (obj, key) {
    return obj[key] ? obj[key] : '';
};
/**
 * 复制数据到剪切板
 * @param copyData
 * @param msg
 */
Vue.prototype.handleCopyData = function (copyData, msg) {
    if (copyData === '') {
        this.$message(msg ? msg : '请输入需要转化数据')
        return;
    }
    var textArea = document.createElement("textarea");
    textArea.style.position = 'fixed';
    textArea.style.top = '0';
    textArea.style.left = '0';
    textArea.style.width = '2em';
    textArea.style.height = '2em';
    textArea.style.padding = '0';
    textArea.style.border = 'none';
    textArea.style.outline = 'none';
    textArea.style.boxShadow = 'none';
    textArea.style.background = 'transparent';
    //key数据获取
    textArea.value = copyData;
    document.body.appendChild(textArea);
    textArea.select();
    try {
        var successful = document.execCommand('copy');
        if (successful) {
            this.$message({
                showClose: true,
                message: '复制成功',
                type: 'success'
            })
        }
    } catch (err) {
        this.$message({
            showClose: true,
            message: '复制失败',
            type: 'warning'
        })
    }
    document.body.removeChild(textArea);
};
/**
 * 跳转链接
 * @param url
 */
Vue.prototype.openWebUrl = function (url) {
    window.open(url);
};
/**
 * Json转化url参数
 * @param json
 * @returns {string}
 */
Vue.prototype.handleJson2UrlParam = function (json) {
    var result = []
    var jsonData = JSON.parse(JSON.stringify(json));
    if(jsonData){
        for(var key in jsonData){
            var value = jsonData[key];
            result.push(key.trim()+ '=' + value);
        }
    }
    return result.join("&");
};
/**
 * key:val->key=val
 * @param keyValStr
 * @returns {string}
 */
Vue.prototype.handleKeyVal2UrlParam = function (keyValStr) {
    var result = []
    if(keyValStr){
        var list = keyValStr.split("\n");
        var index = 0;
        var size = list.length;
        for (; index < size; index++) {
            var pair = list[index];
            if (pair === '') {
                continue;
            }
            var keyVal = new Array();
            keyVal = pair.split(":");
            if (keyVal[0] !== '') {
                var value = keyVal[1] ? keyVal[1].trim() : '';
                result.push(keyVal[0].trim()+ '=' + value);
            }
        }
    }
    return result.join("&");
};
/**
 * key=val->Json
 * @param urlParamStr
 */
Vue.prototype.handleUrlParam2Json = function (urlParamStr) {
    var result={};
    if(urlParamStr){
        var list = urlParamStr.split("&");
        var index = 0;
        var size = list.length;
        for (; index < size; index++) {
            var pair = list[index];
            if (pair === '') {
                continue;
            }
            var keyVal = new Array();
            keyVal = pair.split("=");
            if (keyVal[0] !== '') {
                var value = keyVal[1] ? keyVal[1].trim() : '';
                result[keyVal[0].trim()]= value;
            }
        }
    }
    return JSON.stringify(result);
};


